package com.wy.office.swift.word.handler;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map.Entry;
import java.util.Set;

import org.apache.poi.hwpf.HWPFDocument;
import org.apache.poi.hwpf.usermodel.HeaderStories;
import org.apache.poi.hwpf.usermodel.Range;
import org.apache.poi.xwpf.usermodel.Document;

import com.wy.office.swift.exception.OfficeSwiftException;
import com.wy.office.swift.exception.OperationNotSupportedException;
import com.wy.office.swift.exception.ParamNecessaryException;
import com.wy.office.swift.util.StringUtils;
import com.wy.office.swift.word.model.WordParamModel;

/**
 * doc处理
 * 
 * @author wangyuan
 * @since 2018年7月13日
 */
public class HWPFWordHandler extends AWordHandler {

	@Override
	public List<String> extractVariablesFromSourceFile(String sourcePathName) throws OfficeSwiftException {
		// 参数验证
		if (StringUtils.checkParamIsEmpty(sourcePathName)) {
			throw new ParamNecessaryException("sourcePathName can not be null or empty.");
		}

		List<String> variables = new ArrayList<>();
		InputStream in = null;
		HWPFDocument doc = null;
		try {
			in = new FileInputStream(sourcePathName);
			doc = new HWPFDocument(in);

			// 临时存放变量容器
			Set<String> variableSet = new HashSet<>();

			HeaderStories headerStories = new HeaderStories(doc);
			// 页眉
			Range oddHeaderRange = headerStories.getOddHeaderSubrange();
			Range evenHeaderRange = headerStories.getEvenHeaderSubrange();
			if (oddHeaderRange != null) {
				variableSet.addAll(extractVariables(oddHeaderRange.text()));
			}
			if (evenHeaderRange != null) {
				variableSet.addAll(extractVariables(evenHeaderRange.text()));
			}

			// 页脚
			Range oddFooterRange = headerStories.getOddFooterSubrange();
			Range evenFooterRange = headerStories.getEvenFooterSubrange();
			if (oddFooterRange != null) {
				variableSet.addAll(extractVariables(oddFooterRange.text()));
			}
			if (evenFooterRange != null) {
				variableSet.addAll(extractVariables(evenFooterRange.text()));
			}

			// 正文
			Range range = doc.getRange();
			if (range != null) {
				variableSet.addAll(extractVariables(range.text()));
			}

			variables.addAll(variableSet);
		} catch (Exception e) {
			throw new OfficeSwiftException("参数提取错误", e);
		} finally {
			closeResource(doc);
			closeResource(in);
		}

		return variables;
	}

	@Override
	public void dealOfficeWord(String sourcePathName, String targetPathName, WordParamModel param)
			throws OfficeSwiftException {
		// 参数验证
		if (StringUtils.checkParamIsEmpty(sourcePathName, targetPathName)) {
			throw new ParamNecessaryException("sourcePathName or targetPathName can not be null or empty.");
		}

		if (param == null) {
            param = new WordParamModel();
        }

		InputStream in = null;
		OutputStream out = null;
		try {
			ByteArrayOutputStream resultOut = dealOfficeWord(sourcePathName, param);
			// 写入新的文件
			File newFile = new File(targetPathName);
			out = new FileOutputStream(newFile);
			resultOut.writeTo(out);
		} catch (Exception e) {
			throw new OfficeSwiftException(e);
		} finally {
			closeResource(out);
			closeResource(in);
		}
	}

	@Override
	public ByteArrayOutputStream dealOfficeWord(String sourcePathName, WordParamModel param)
			throws OfficeSwiftException {
		// 参数验证
		if (StringUtils.checkParamIsEmpty(sourcePathName)) {
			throw new ParamNecessaryException("sourcePathName can not be null or empty.");
		}

		if (param == null) {
			param = new WordParamModel();
		}

		InputStream in = null;
		ByteArrayOutputStream out = null;
		HWPFDocument doc = null;
		try {
			in = new FileInputStream(sourcePathName);
			doc = new HWPFDocument(in);

			HeaderStories headerStories = new HeaderStories(doc);
			// 页眉
			Range oddHeaderRange = headerStories.getOddHeaderSubrange();
			Range evenHeaderRange = headerStories.getEvenHeaderSubrange();
			if (oddHeaderRange != null) {
				for (Entry<String, String> item : param.getSimpleParams().entrySet()) {
					oddHeaderRange.replaceText(VARIABLE_PREFIX + item.getKey() + VARIABLE_SUFFIX, item.getValue());
				}
			}
			if (evenHeaderRange != null) {
				for (Entry<String, String> item : param.getSimpleParams().entrySet()) {
					evenHeaderRange.replaceText(VARIABLE_PREFIX + item.getKey() + VARIABLE_SUFFIX, item.getValue());
				}
			}

			// 页脚
			Range oddFooterRange = headerStories.getOddFooterSubrange();
			Range evenFooterRange = headerStories.getEvenFooterSubrange();
			if (oddFooterRange != null) {
				for (Entry<String, String> item : param.getSimpleParams().entrySet()) {
					oddFooterRange.replaceText(VARIABLE_PREFIX + item.getKey() + VARIABLE_SUFFIX, item.getValue());
				}
			}
			if (evenFooterRange != null) {
				for (Entry<String, String> item : param.getSimpleParams().entrySet()) {
					evenFooterRange.replaceText(VARIABLE_PREFIX + item.getKey() + VARIABLE_SUFFIX, item.getValue());
				}
			}

			// 正文
			Range range = doc.getRange();
			if (range != null) {
				for (Entry<String, String> item : param.getSimpleParams().entrySet()) {
					range.replaceText(VARIABLE_PREFIX + item.getKey() + VARIABLE_SUFFIX, item.getValue());
				}
			}

			// 写入新的字节流
			out = new ByteArrayOutputStream();
			doc.write(out);
		} catch (Exception e) {
			throw new OfficeSwiftException(e);
		} finally {
			closeResource(doc);
			closeResource(in);
		}
		return out;
	}

    @Override
    public Document dealOfficeWord(Document document, WordParamModel param) throws OfficeSwiftException {
        throw new OperationNotSupportedException();
    }

    @Override
    public Document mergeDocment(Document source, Document target) throws OfficeSwiftException {
        throw new OperationNotSupportedException();
    }
}
